﻿using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;

namespace TpBaseObjects.Base {

    public abstract class AbstractProjectSheet {

        #region Members

        private Worksheet mySheet;
        private Workbook myBook;
        public delegate int GetFreeNumber(string bereich, Worksheet sheet);
        private List<ProjectRow> myRows = new List<ProjectRow>();

        #endregion

        #region Constructor

        public AbstractProjectSheet(Worksheet sh) {
            this.mySheet = sh;
            this.myBook = sh.Parent;
        }

        #endregion

        #region Properties

        public List<ProjectRow> MyRows {
            get { return myRows; }
        }

        public Worksheet MySheet {
            get { return this.mySheet; }
            
        }

        public Workbook MyBook {
            get { return this.myBook; }
        }

        #endregion

        #region Methods

        public void Write(string bereich, Worksheet sourceSheet, GetFreeNumber getFreeNumber, bool withFormats) {
            if (MyRows.Count != 0) {

                foreach (ProjectRow row in MyRows) {
                    int freeRowNumber = getFreeNumber(bereich, mySheet);
                    Range sourceRow = sourceSheet.Rows[row.RowNumber];
                    Range targetRow = GetNewRow(mySheet, freeRowNumber);

                    ((Microsoft.Office.Interop.Excel._Worksheet)sourceSheet).Activate();
                    sourceRow.Select();
                    sourceRow.Copy();
                    ((Microsoft.Office.Interop.Excel._Worksheet)mySheet).Activate();
                    targetRow.Select();
                    targetRow.PasteSpecial(XlPasteType.xlPasteValues, XlPasteSpecialOperation.xlPasteSpecialOperationNone, SkipBlanks: false, Transpose: false);
                    targetRow.PasteSpecial(XlPasteType.xlPasteComments, XlPasteSpecialOperation.xlPasteSpecialOperationNone, SkipBlanks: false, Transpose: false);
                    if (withFormats) {
                        targetRow.PasteSpecial(XlPasteType.xlPasteFormats, Operation: XlPasteSpecialOperation.xlPasteSpecialOperationNone, SkipBlanks: false, Transpose: false);
                    }

                }
            }
        }

        public void WriteJob(string job, string subJob, DateTime jobDate, string lf, string userName,
                int rechnungsNummer, string fileName, string display) {
            WriteJob(job, subJob, jobDate, lf, userName, rechnungsNummer, fileName, display, "", false);
        }

        public void WriteJob(string job, string subJob, DateTime jobDate, string lf, string userName,
                int rechnungsNummer, string fileName, string display, string user2, bool exported) {

            Range rCol = this.mySheet.Columns["AF"];
            Range aCell = this.mySheet.Cells[301, "AF"];
            Range r1 = null;
            //Range r2 = null;
            object toFind = job;
            int jobRow = GetNextRowNumber(this.mySheet, rCol, aCell, toFind, true);
            if (jobRow == 0) {
                return;
            }
            int firstRow = jobRow;
            r1 = this.mySheet.Rows[jobRow];

            bool weiter = false;
            try {
                while (weiter == false) {

                    ProjectRow myRow = new ProjectRow(r1);

                    if (myRow.Job == job && myRow.JobDetail == subJob) {

                        if (myRow.LeistungExported) {
                            Range newR1 = mySheet.Rows[jobRow, Missing.Value];
                            ((Microsoft.Office.Interop.Excel._Worksheet)mySheet).Activate();
                            newR1.Select();
                            newR1.Copy();
                            newR1.Insert(Shift: XlInsertShiftDirection.xlShiftDown);

                            newR1 = mySheet.Rows[jobRow + 1, Missing.Value];
                            myRow = new ProjectRow(newR1);

                        }
                        myRow.JobDatum = jobDate;
                        //myRow.Leistung = job;
                        myRow.Durchführender1 = userName;
                        myRow.Durchführender2 = user2;
                        myRow.JobOrt = lf;

                        if (rechnungsNummer != 0) {
                            myRow.RechnungsNummer = rechnungsNummer;
                        }

                        if (!String.IsNullOrEmpty(fileName)) {
                            Range r3 = r1.Cells[1, "J"];
                            r3.Hyperlinks.Add(r3, Address: fileName, TextToDisplay: display);
                        }
                        myRow.SetFontBold(false);
                        if (exported) {
                            if (myRow.JobEvidenz) {
                                myRow.SetExported("Je");
                            } else {
                                myRow.SetExported("Le");
                            }
                        } else {
                            myRow.SetExported("");
                        }
                        weiter = true;
                    } else {
                        aCell = this.mySheet.Cells[jobRow, "AF"];
                        jobRow = GetNextRowNumber(this.mySheet, rCol, aCell, toFind, true);
                        r1 = this.mySheet.Rows[jobRow];
                        if (jobRow == firstRow) {
                            weiter = true;
                        }
                    }

                }



            } catch (Exception ex) {
                //log.Add("WriteJob(" + jobRow.ToString() + ")", ex);
                Debug.Print(ex.Message);
            }
        }

        #endregion

        #region Functions

        public Range GetNewRow(Worksheet sh, int startRow) {
            Range row = sh.Rows[startRow];
            return row;
        }

        private static int GetNextRowNumber(Worksheet sh, Range rCol, Range activeCell, object toFind) {
            return GetNextRowNumber(sh, rCol, activeCell, toFind, false);
        }

        private static int GetNextRowNumber(Worksheet sh, Range rCol, Range activeCell, object toFind, bool exact) {
            int ret = 0;
            Range r1;
            if (!exact) {
                r1 = rCol.Find(What: toFind, After: activeCell, SearchDirection: XlSearchDirection.xlNext, MatchCase: exact, LookAt: XlLookAt.xlPart);
            } else {
                r1 = rCol.Find(toFind, activeCell, SearchDirection: XlSearchDirection.xlNext, MatchCase: exact, LookAt: XlLookAt.xlWhole);
            }
            if (r1 != null) {
                ret = r1.Row;
            }
            return ret;
        }

        #endregion

    }
}
